package org.douxiaoban.client.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.douxiaoban.client.api.CollectionRecord;
import org.douxiaoban.client.api.DoubanApi;
import org.douxiaoban.client.api.DoubanList.DoubanListType;
import org.douxiaoban.client.api.ReviewRecord;
import org.douxiaoban.client.api.SubjectRecord;
import org.douxiaoban.client.api.TopSubjectParser;
import org.douxiaoban.client.api.TopSubjectRecord;
import org.douxiaoban.client.api.UserInfoData;
import org.douxiaoban.client.app.App;
import org.douxiaoban.client.app.Assistant;
import org.douxiaoban.client.model.BundleSerializable;
import org.douxiaoban.data.DoubanBaseData;
import org.douxiaoban.data.MailData;
import org.douxiaoban.data.MiniBlogItemData;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.client.DoubanService;
import com.google.gdata.data.douban.CollectionEntry;
import com.google.gdata.data.douban.Status;
import com.google.gdata.data.douban.SubjectEntry;
import com.google.gdata.data.douban.Tag;
import com.google.gdata.data.extensions.Rating;
import com.google.gdata.util.ServiceException;

/**
 * Created by IntelliJ IDEA. User: huangzhongkun Date: 11-5-23 Time: 下午11:35
 */
public class ThreadTool {
	private static ThreadTool m_threadTool;
	private Context m_context;

	public ThreadTool(Context context) {
		m_context = context;
	}

	public static ThreadTool instace(Context context) {
		if (null == m_threadTool) {
			m_threadTool = new ThreadTool(context);
		}
		return m_threadTool;
	}

	/**
	 * 获取数据
	 * 
	 * @param
	 * @return
	 * @exception
	 */
	public void getListData(Handler handler, String userId, int startIndex,
			int max, DoubanListType type, boolean isRefresh) {
		DoubanListThread listThread = null;// = new DoubanListThread();
		switch (type) {
		case CONTACTS:
			listThread = new UserThread(handler, userId, startIndex, max,
					isRefresh, true);
			break;
		case FRIENDS:
			listThread = new UserThread(handler, userId, startIndex, max,
					isRefresh, false);
			break;
		case CONTACTS_MINIBLOG:
			listThread = new MiniblogThread(handler, userId, startIndex, max,
					isRefresh, true);
			break;
		case USER_MINIBLOG:
			listThread = new MiniblogThread(handler, userId, startIndex, max,
					isRefresh, false);
			break;
		case MAIL_INBOX:
			listThread = new MailThread(handler, userId, startIndex, max,
					isRefresh, true);
			break;
		case MAIL_OUTBOX:
			listThread = new MailThread(handler, userId, startIndex, max,
					isRefresh, false);
			break;
		default:

			break;
		}

		if (null != listThread) {
			listThread.start();
		}
	}

	// //get more
	// public void getContactsMiniBlog(String userId, Handler handler, int
	// start, int max){
	// new ThreadMiniBlog(userId, handler, start, max, true).start();
	// }
	// //get more
	// public void getUserMiniBlog(String userId, Handler handler, int start,
	// int max){
	// new ThreadMiniBlog(userId, handler, start, max, false).start();
	// }
	//
	// //refresh...
	// public void getContactsMiniBlogRefresh(String userId, Handler handler,
	// int start, int max){
	// new ThreadMiniBlog(userId, handler, start, max, true, true).start();
	// }
	// public void getUserMiniBlogRefresh(String userId, Handler handler, int
	// start, int max){
	// new ThreadMiniBlog(userId, handler, start, max, false, true).start();
	// }
	// //refresh

	/**
	 * 创建我说
	 * 
	 * @param content
	 *            我说的内容
	 * @param handler
	 *            线程回调的handler
	 */
	public void createSaying(String content, Handler handler) {
		new ThreadSaying(content, handler).start();
	}

	/**
	 * 删除广播
	 * 
	 * @param id
	 *            广播id值
	 * @param handler
	 *            回传的handler
	 */
	public void delMiniBlog(String id, int pos, Handler handler) {
		new ThreadDelMiniblog(id, pos, handler).start();
	}

	/**
	 * 回应我说
	 * 
	 * @param content
	 *            回应的内容
	 * @param sayingId
	 *            被回应的我说id
	 * @param handler
	 */
	public void revSaying(String content, String sayingId, Handler handler) {
		new ThreadRev(content, sayingId, handler, true).start();
	}

	/**
	 * 回应推荐
	 * 
	 * @param content
	 *            回应的内容
	 * @param recommendId
	 *            被回应的推荐id
	 * @param handler
	 */
	public void revRecommendations(String content, String recommendId,
			Handler handler) {
		new ThreadRev(content, recommendId, handler, false).start();
	}

	/**
	 * 获取头像/图片
	 * 
	 * @param userId
	 * @param url
	 *            图片地址的url
	 * @param handler
	 * @param position
	 *            图片将要被加载的位置
	 */
	public void getAvatar(String userId, String url, Handler handler,
			int position) {
		new ThreadAvatar(url, handler, position, true).start();
	}

	public void sendMail(Handler handler, String userId, String title,
			String content) {
		new ThreadSendMail(handler, userId, title, content).start();
	}

	public void sendMail(Handler handler, String userId, String title,
			String content, String catchToken, String catchStr) {
		new ThreadSendMail(handler, userId, title, content, catchToken,
				catchStr).start();
	}

	// public void getMailList(Handler handler, int start, int max,
	// DoubanListType type){
	// new ThreadMailList(handler, start, max, type).start();
	// }
	//
	// public void getMailListRe(Handler handler, int start, int max,
	// DoubanListType type){
	// new ThreadMailList(handler, start, max, type, true).start();
	// }

	// public void getOutboxMail(Handler handler, int start, int max){
	// new ThreadMailList(handler, start, max, false).start();
	// }

	public void getOneMail(Handler handler, String mailId) {
		new ThreadOneMail(handler, mailId).start();
	}

	public void delMail(Handler handler, String mailId, int listIndex) {
		new ThreadDelMail(handler, mailId, listIndex).start();
	}

	public void getImage(String url, Handler handler, int position) {
		new ThreadAvatar(url, handler, position, false).start();
	}

	/**
	 * 
	 * @param userId
	 * @param handler
	 */
	public void getUserInfo(String userId, Handler handler) {
		new ThreadUserInfo(userId, handler).start();

	}

	// /**
	// * 关注列表
	// * @param userId 用户id
	// * @param handler 回调的handler
	// * @param startIndex 开始的索引
	// * @param maxReq 返回最大条数
	// */
	// public void getUserContacts(String userId, Handler handler,
	// int startIndex, int maxReq){
	//
	// new ThreadUserList(userId, handler, startIndex, maxReq, true).start();
	// }

	/**
	 * 好友列表
	 * 
	 * @param userId
	 * @param handler
	 * @param startIndex
	 * @param maxReq
	 */
	// public void getUserFriends(String userId, Handler handler, int
	// startIndex, int maxReq){
	//
	// new ThreadUserList(userId, handler, startIndex, maxReq, false).start();
	// }
	// ------------------------------------------------------------------------------------------------
	/**
	 * 豆瓣获取列表数据基类 Description: Copyright: Copyright (c)2011
	 * 
	 * @author: 6a209 Create at: 2011-7-17 下午05:24:05
	 */
	private abstract class DoubanListThread extends Thread {
		protected Handler mHandler;
		protected String mUserId;
		protected int mStartIndex;
		protected int mMax;
		protected boolean mIsRefresh;

		public DoubanListThread() {

		}

		public DoubanListThread(Handler handler, String userId, int startIndex,
				int max, boolean isRefresh) {
			mHandler = handler;
			mUserId = userId;
			mStartIndex = startIndex;
			mMax = max;
			mIsRefresh = isRefresh;
		}

		public abstract void reqData();

		public void run() {
			reqData();
		}
	}

	/**
	 * 获取miniblog线程 Description: Copyright: Copyright (c)2011
	 * 
	 * @author: 6a209 Create at: 2011-7-17 下午08:51:22
	 */
	private class MiniblogThread extends DoubanListThread {
		private MiniBlogListSerialz mMiniBlog;
		private ArrayList<MiniBlogItemData> mList;
		private boolean mIsContacts;

		public MiniblogThread(Handler handler, String userId, int startIndex,
				int maxReq, boolean isRefresh, boolean isContacts) {

			super(handler, userId, startIndex, maxReq, isRefresh);
			mIsContacts = isContacts;
		}

		public void reqData() {
			mList = App.getDouanApiInstance().getMiniblog(mUserId, mStartIndex,
					mMax, mIsContacts);
			mMiniBlog = new MiniBlogListSerialz(mList, mIsRefresh);
			sendMessage(mHandler, mMiniBlog, Assistant.MSG_DOUBAN_LIST_DATA,
					Assistant.KEY_DOUBAN_LIST_DATA);
		}
	}

	/**
	 * 获取mail的线程 Description: Copyright: Copyright (c)2011
	 * 
	 * @author: 6a209 Create at: 2011-7-17 下午10:26:39
	 */
	private class MailThread extends DoubanListThread {
		private MailListSerialz mMailSerialz;
		private ArrayList<MailData> mList;
		private boolean mIsInbox;

		public MailThread(Handler handler, String userId, int start, int max,
				boolean isRefresh, boolean isInbox) {
			super(handler, userId, start, max, isRefresh);
			mIsInbox = isInbox;
		}

		public void reqData() {
			DoubanApi api = App.getDouanApiInstance();
			mList = api.getMail(mStartIndex, mMax, mIsInbox);
			mMailSerialz = new MailListSerialz(mList, mIsRefresh);
			sendMessage(mHandler, mMailSerialz, Assistant.MSG_DOUBAN_LIST_DATA,
					Assistant.KEY_DOUBAN_LIST_DATA);
		}
	}

	/**
	 * 获取用户列表 Description: Copyright: Copyright (c)2011
	 * 
	 * @author: 6a209 Create at: 2011-7-18 下午02:46:25
	 */
	private class UserThread extends DoubanListThread {
		private UserInfoListSerialz mSerialz;
		private ArrayList<UserInfoData> mList;
		private boolean mIsContacts;

		public UserThread(Handler handler, String userId, int startIndex,
				int maxResult, boolean isRefresh, boolean isContacts) {

			super(handler, userId, startIndex, maxResult, isRefresh);
			mIsContacts = isContacts;
		}

		public void reqData() {
			DoubanApi api = App.getDouanApiInstance();
			mList = api.getUsers(mUserId, mStartIndex, mMax, mIsContacts);
			mSerialz = new UserInfoListSerialz(mList, mIsRefresh);
			sendMessage(mHandler, mSerialz, Assistant.MSG_DOUBAN_LIST_DATA,
					Assistant.KEY_DOUBAN_LIST_DATA);
		}
	}

	// -------------------------------------------------------------------------------------------------------------
	/**
	 * 回应线程
	 * 
	 * @author semir
	 * 
	 */
	private class ThreadRev extends Thread {
		private Handler m_handler;
		private String m_content;
		private String m_sId;
		private boolean m_bIsSaying;

		public ThreadRev(String content, String id, Handler handler,
				boolean isSaying) {
			m_handler = handler;
			m_content = content;
			m_sId = id;
			m_bIsSaying = isSaying;
		}

		@Override
		public void run() {
			boolean isSuccess;
			if (m_bIsSaying) {
				isSuccess = App.getDouanApiInstance().revSaying(m_content,
						m_sId);
			} else {
				isSuccess = App.getDouanApiInstance().revRecommend(m_content,
						m_sId);
			}
			Bundle bundle = new Bundle();
			// 和我说一样,只返回一个布尔值!
			bundle.putBoolean(Assistant.TOOLS_KEY_SAYING, isSuccess);
			sendMessage(m_handler, bundle, Assistant.TOOLS_MSG_SAYING);
		}
	}

	private class ThreadDelMiniblog extends Thread {
		private Handler m_handler;
		private String m_id;
		private int m_iPosition;

		public ThreadDelMiniblog(String id, int position, Handler handler) {
			m_handler = handler;
			m_id = id;
			m_iPosition = position;
		}

		@Override
		public void run() {
			boolean isSuccess = App.getDouanApiInstance().deleteMiniBlog(m_id);
			Bundle bundle = new Bundle();
			bundle.putBoolean(Assistant.TOOLS_KEY_DEL, isSuccess);
			bundle.putInt(Assistant.TOOLS_KEY_POSITION, m_iPosition);
			sendMessage(m_handler, bundle, Assistant.TOOLS_MSG_DEL);
		}

	}

	private class ThreadSaying extends Thread {
		private Handler m_handler;
		private String m_content;

		public ThreadSaying(String content, Handler handler) {
			m_handler = handler;
			m_content = content;
		}

		@Override
		public void run() {
			boolean isSuccessed = App.getDouanApiInstance().createSaying(
					m_content);
			Bundle bundle = new Bundle();
			Message msg = new Message();
			bundle.putBoolean(Assistant.TOOLS_KEY_SAYING, isSuccessed);
			msg.what = Assistant.TOOLS_MSG_SAYING;
			msg.setData(bundle);
			m_handler.sendMessage(msg);
		}
	}

	private class ThreadUserInfo extends Thread {
		private Handler m_handler;
		private String m_sUserId;

		public ThreadUserInfo(String userId, Handler handler) {
			m_handler = handler;
			m_sUserId = userId;
		}

		@Override
		public void run() {

			UserInfoData userInfo;
			if (null == m_sUserId) {
				userInfo = App.getDouanApiInstance().getAuthorizedUser();
			} else {
				userInfo = App.getDouanApiInstance().getUserInfo(m_sUserId);
			}
			UserInfoSerialz serialz = new UserInfoSerialz(userInfo);
			sendMessage(m_handler, serialz, Assistant.TOOLS_MSG_USINFO,
					Assistant.TOOLS_KEY_USER_INFO);
		}

	}

	// 获取Avatar 线程!
	private class ThreadAvatar extends Thread {
		private Handler m_handler;
		private String m_sUrl;
		private int m_iPosition;
		// private String m_sUserId;
		private boolean m_bIsAvatar;

		public ThreadAvatar(String url, Handler handler, int position,
				boolean isAvatar) {

			m_sUrl = url;
			m_handler = handler;
			m_iPosition = position;
			m_bIsAvatar = isAvatar;
		}

		@Override
		public void run() {
			Bitmap avatar = null;// =
									// DataBaseDriver.instaceDb(m_context).getAvatar(m_sUserId);
			if (null == avatar) {
				// UserInfoData userInfo =
				// DoubanApi.getInstance().getUserInfo(m_sUserId);
				try {
					avatar = loadImgByURL(new URL(m_sUrl));
				} catch (MalformedURLException e) {
					Log.e("ThreadAvatar_url", e.getMessage());
				}
			}
			ImageSerialz image = new ImageSerialz(avatar, m_iPosition);
			if (m_bIsAvatar) {
				sendMessage(m_handler, image, Assistant.TOOLS_MSG_AVATAR,
						Assistant.TOOLS_KEY_AVATAR);
			} else {
				sendMessage(m_handler, image, Assistant.TOOLS_MSG_IMAGE,
						Assistant.TOOLS_KEY_IMAGE);
			}

		}
	}

	private class ThreadOneMail extends Thread {
		private Handler mHandler;
		private String mMailId;

		public ThreadOneMail(Handler handler, String id) {
			mHandler = handler;
			mMailId = id;
		}

		@Override
		public void run() {
			DoubanApi api = App.getDouanApiInstance();
			MailData mailData = api.getOneMail(mMailId);
			MailSerialz mail = new MailSerialz(mailData);
			sendMessage(mHandler, mail, Assistant.TOOLS_MSG_ONE_MAIL,
					Assistant.TOOLS_KEY_ONE_MAIL);
		}
	}

	private class ThreadSendMail extends Thread {
		private Handler mHandler;
		private String mContent;
		private String mTitle;
		private String mCatchaToken;
		private String mCatchStr;
		private String mUserId;
		private boolean mHasToken;

		public ThreadSendMail(Handler handler, String userId, String title,
				String content) {
			mHasToken = false;
			mUserId = userId;
			mHandler = handler;
			mContent = content;
			mTitle = title;
		}

		// 带验证码
		public ThreadSendMail(Handler handler, String userId, String title,
				String content, String catchToken, String catchStr) {
			mHasToken = true;
			mUserId = userId;
			mHandler = handler;
			mContent = content;
			mTitle = title;
			mCatchaToken = catchToken;
			mCatchStr = catchStr;
		}

		@Override
		public void run() {
			DoubanApi api = App.getDouanApiInstance();
			int status;
			Bundle bundle = new Bundle();
			if (mHasToken) {
				status = api.sendMail(mUserId, mTitle, mContent, mCatchaToken,
						mCatchStr, bundle);
			} else {
				status = api.sendMail(mUserId, mTitle, mContent, bundle);
			}
			// 弄了半天也没想到好的枚举装int 只好这样了!
			// bundle.putInt(Assistant.KEY_SUCCESS,status);
			sendMessage(mHandler, bundle, status);
		}
	}

	private class ThreadDelMail extends Thread {
		private String mMailId;
		private Handler mHandler;
		// private boolean mIsInbox;
		private int mListIndex;

		public ThreadDelMail(Handler handler, String mailId, int listIndex) {
			mMailId = mailId;
			mHandler = handler;
			// mIsInbox = isInbox;
			mListIndex = listIndex;
		}

		@Override
		public void run() {
			DoubanApi api = App.getDouanApiInstance();
			boolean isSuccess = api.deleteMail(mMailId);
			Bundle bundle = new Bundle();
			bundle.putBoolean(Assistant.KEY_SUCCESS, isSuccess);
			// bundle.putBoolean(Assistant.KEY_IS_INBOX, mIsInbox);
			bundle.putInt(Assistant.KEY_MAIL_INDEX, mListIndex);
			sendMessage(mHandler, bundle, Assistant.MSG_DEL_MAIL);
		}
	}

	public class ImageSerialz implements Serializable {
		public Bitmap m_bitmap;
		public int m_iPosition;

		public ImageSerialz(Bitmap bitmap, int position) {
			m_bitmap = bitmap;
			m_iPosition = position;
		}
	}

	// -------------------------------------------------------------------------
	/**
	 * 
	 * Description: 线程中传递的基类。。 Copyright: Copyright (c)2011
	 * 
	 * @author: 6a209 Create at: 2011-7-18 下午09:19:58
	 */
	public class DoubanListSerialz implements Serializable {
		private ArrayList<? extends DoubanBaseData> mList;
		private boolean mIsRefresh;

		public DoubanListSerialz(ArrayList<? extends DoubanBaseData> list,
				boolean isRefresh) {
			mList = list;
			mIsRefresh = isRefresh;
		}

		public ArrayList<? extends DoubanBaseData> getList() {
			return mList;
		}

		public boolean getIsRefresh() {
			return mIsRefresh;
		}
	}

	public class MiniBlogListSerialz extends DoubanListSerialz {

		public MiniBlogListSerialz(ArrayList<MiniBlogItemData> list,
				boolean isRefresh) {
			super(list, isRefresh);
		}
	}

	public class UserInfoListSerialz extends DoubanListSerialz {

		public UserInfoListSerialz(ArrayList<UserInfoData> list,
				boolean isRefresh) {
			super(list, isRefresh);
		}

	}

	public class MailListSerialz extends DoubanListSerialz {

		public MailListSerialz(ArrayList<MailData> list, boolean isRefresh) {
			super(list, isRefresh);
		}
	}

	// ----------------------------------------------------------------------------

	public class UserInfoSerialz implements Serializable {
		public UserInfoData m_userInfo;

		public UserInfoSerialz(UserInfoData userInfo) {
			m_userInfo = userInfo;
		}
	}

	public class MailSerialz implements Serializable {
		public MailData mMailData;

		public MailSerialz(MailData mailData) {
			mMailData = mailData;
		}
	}

	// ---
	// ---------------------------------- by kun-----------------------------
	// --
	/**
	 * Top subject
	 * 
	 * @param handler
	 * @param type
	 */
	public void startThreadFetchTopSubject(Handler handler, String type) {
		new ThreadFetchTopSubject(handler, type).start();
	}

	private class ThreadFetchTopSubject extends Thread {
		private Handler _handler;
		private String _type;

		public ThreadFetchTopSubject(Handler handler, String type) {
			_handler = handler;
			_type = type;
		}

		@Override
		public void run() {

			ArrayList<TopSubjectRecord> topSubjectRecords = null;

			if (_type.equals(Assistant.STATUS_MOVICE))
				topSubjectRecords = TopSubjectParser.getHotMovie();

			if (_type.equals(Assistant.STATUS_BOOK))
				topSubjectRecords = TopSubjectParser.getNewBook();

			if (_type.equals(Assistant.STATUS_MUSIC))
				topSubjectRecords = TopSubjectParser.getNewMusic();

			if (topSubjectRecords != null) {
				Bundle bundle = new Bundle();
				BundleSerializable bs = new BundleSerializable();
				bs.tsr = topSubjectRecords;

				bundle.putSerializable(Assistant.KEY_OF_SUBJECT, bs);

				sendMessage(_handler, Assistant.FETCH_PARSER_TOP_DONE, bundle);
			} else {
				sendMessage(_handler, Assistant.FETCH_PARSER_TOP_FAIL, null);
			}
		}
	}

	public void startThreadSearchSubject(Handler handler, String type,
			String keyword, int start, int maxResult) {
		new ThreadSearchSubject(handler, keyword, type, start, maxResult)
				.start();
	}

	private class ThreadSearchSubject extends Thread {
		private Handler _handler;
		private String _keyword;
		private String _type;
		private int _start_index;
		private int _max_result;

		public ThreadSearchSubject(Handler handler, String keyword,
				String type, int start_index, int max_result) {
			_handler = handler;
			_keyword = keyword;
			_type = type;
			_start_index = start_index;
			_max_result = max_result;
		}

		@Override
		public void run() {

			ArrayList<SubjectRecord> subjectRecordArrayList = null;

			try {
				subjectRecordArrayList = App.getDouanApiInstance()
						.searchSubject(_type, _start_index, _keyword,
								_max_result);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ServiceException e) {
				e.printStackTrace();
			}

			if (subjectRecordArrayList != null) {
				Bundle bundle = new Bundle();
				BundleSerializable bundleSerializable = new BundleSerializable();
				bundleSerializable.sjs = subjectRecordArrayList;
				bundle.putSerializable(Assistant.KEY_OF_SUBJECT,
						bundleSerializable);

				sendMessage(_handler, Assistant.FETCH_SEARCH_DONE, bundle);
			} else {
				sendMessage(_handler, Assistant.FETCH_SEARCH_FAIL, null);
			}
		}
	}

	/**
	 * 更新用户的收藏 数据，提交成功返回一个CollectionEntry,这里判断无异常则为成功
	 * 
	 * @param handler
	 * @param collectionEntry
	 * @param status
	 * @param tags
	 * @param rating
	 */
	public void startThreadUpdateSubjectCollection(Handler handler,
			CollectionEntry collectionEntry, String status, String tags,
			int rating, String summary) {
		new ThreadUpdateSubjectCollection(handler, status, tags, rating,
				collectionEntry, summary).start();
	}

	private class ThreadUpdateSubjectCollection extends Thread {
		private Handler handler;
		private CollectionEntry collectionEntry;
		private String status;
		private String tags;
		private int rating;
		private String summary;

		public ThreadUpdateSubjectCollection(Handler handler, String status,
				String tags, int rating, CollectionEntry collectionEntry,
				String summary) {
			this.handler = handler;
			this.collectionEntry = collectionEntry;
			this.status = status;
			this.tags = tags;
			this.rating = rating;
			this.summary = summary;
		}

		@Override
		public void run() {
			String[] tempTag = tags.split(" ");
			List<Tag> tagList = new ArrayList<Tag>();

			// 格式化tags字符串, 过滤为空的字符串
			for (String s : tempTag) {
				if (s != null && !s.equals("")) {
					Tag tag = new Tag();
					tag.setName(s);
					tagList.add(tag);
				}
			}
			Rating myRating = new Rating();
			myRating.setValue(rating);

			CollectionEntry newCollectionEntry = null;
			try {
				newCollectionEntry = App.getDouanApiInstance().doubanService
						.updateCollection(collectionEntry, new Status(status),
								tagList, myRating, new PlainTextConstruct(
										summary));
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ServiceException e) {
				e.printStackTrace();
			}

			if (newCollectionEntry != null) {
				sendMessage(handler, Assistant.FETCH_UPDATE_COLLECTION_DONE,
						null);
			} else {
				sendMessage(handler, Assistant.FETCH_UPDATE_COLLECTION_FAIL,
						null);
			}

		}
	}// ThreadUpdateSubjectCollection.class

	// -------------------------------------------------------------------------

	/**
	 * 获取用户的详细收藏数据，用于在图书电影音乐获取用户的收藏
	 * 
	 * @param handler
	 * @param collection_url
	 */
	public void startThreadFetchSubjectCollection(Handler handler,
			String collection_url) {
		new ThreadFetchSubjectCollection(handler, collection_url).start();
	}

	private class ThreadFetchSubjectCollection extends Thread {
		private Handler handler;
		private String collection_url;

		public ThreadFetchSubjectCollection(Handler handler,
				String collection_url) {
			this.handler = handler;
			this.collection_url = collection_url;
		}

		@Override
		public void run() {
			String[] temp = collection_url.split("/");

			CollectionEntry collectionEntry = null;
			try {
				collectionEntry = App.getDouanApiInstance().doubanService
						.getCollection(temp[temp.length - 1]);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ServiceException e) {
				e.printStackTrace();
			}

			if (collectionEntry != null) {
				CollectionRecord collectionRecord = App.getDouanApiInstance()
						.convertEntriesToRecord(collectionEntry, 10);
				collectionRecord.collectionEntry = collectionEntry;

				Bundle bundle = new Bundle();
				bundle.putSerializable(Assistant.KEY_OF_COLLECTION,
						collectionRecord);

				sendMessage(handler, Assistant.FETCH_USER_COLLECTION_DONE,
						bundle);
			} else {
				sendMessage(handler, Assistant.FETCH_USER_COLLECTION_FAIL, null);
			}
		}
	}// ThreadFetchSubjectCollection.class

	// -------------------------------------------------------------------------
	/**
	 * 开启获取评论者头像线程 该线程将一次性获取一个多个头像图片再返回一个Bitmap的集合，一次性更新评论视图
	 * 
	 * @param handler
	 * @param urls
	 *            图片地址集合
	 * @param context
	 *            用于获取Drawable
	 */
	public void startThreadFetchReviewAvatar(Handler handler, String[] urls,
			Context context) {
		new ThreadFetchReviewAvatar(handler, urls, context).start();
		// TODO :收藏列表的封面图片是否可以考虑按这种多个图片一起获取的方式,达到更高的效率？
	}

	/**
	 * Thread-Review-Avatar
	 */
	private class ThreadFetchReviewAvatar extends Thread {
		private Handler handler;
		private String[] urls;
		private Context context;

		public ThreadFetchReviewAvatar(Handler handler, String[] urls,
				Context context) {
			this.handler = handler;
			this.urls = urls;
			this.context = context;
		}

		@Override
		public void run() {
			ArrayList<Bitmap> avatars = new ArrayList<Bitmap>();
			int i = 0;

			for (String u : urls) {
				try {
					avatars.add(loadImgByURL(new URL(u)));
				} catch (MalformedURLException e) {
					// do something...
				}
			}

			if (avatars != null && avatars.size() > 0) {
				Bundle bundle = new Bundle();
				BundleSerializable bs = new BundleSerializable();
				bs.reviewAvatars = avatars;
				bundle.putSerializable(Assistant.KEY_OF_IMAGE, bs);
				sendMessage(handler, Assistant.FETCH_REVIEW_AVATAR_DONE, bundle);
			}
		}
	}// ThreadFetchReviewAvatar.class

	// -------------------------------------------------------------------------

	/**
	 * 开启获取完整的评论线程，由于豆瓣api不提供该接口，所有用httpConnection解析评论的html 利用正则匹配
	 * 两个固定的标签值，利用Html.fromHtml过滤已有的html标签
	 * 
	 * @param handler
	 * @param reviewId
	 *            评论id
	 * @param type
	 *            条目类型
	 */
	public void startThreadFetchReviewFull(Handler handler, String reviewId,
			String type) {
		new ThreadFetchReviewFull(handler, reviewId, type).start();
	}

	/**
	 * Thread-Fetch-Review-Full
	 */
	private class ThreadFetchReviewFull extends Thread {
		private Handler handler;
		private String reviewId;
		private String type;

		public ThreadFetchReviewFull(Handler handler, String reviewId,
				String type) {
			this.handler = handler;
			this.reviewId = reviewId;
			this.type = type;
		}

		@Override
		public void run() {
			if (reviewId != null) {
				String[] split = reviewId.split("/");
				reviewId = split[split.length - 1];
			}

			StringBuffer stringBuffer = new StringBuffer();
			String result = "";

			try {
				URL url = new URL("http://" + type + ".douban.com/review/"
						+ reviewId + "/");
				HttpURLConnection httpURLConnection = (HttpURLConnection) url
						.openConnection();
				InputStreamReader ir = new InputStreamReader(
						httpURLConnection.getInputStream());
				BufferedReader br = new BufferedReader(ir);
				String temp;
				while ((temp = br.readLine()) != null) {
					stringBuffer.append(temp);
				}
				br.close();
				ir.close();

				Pattern pattern = Pattern.compile(
						"v\\:description\\\"\\>.*review\\-panel",
						Pattern.CASE_INSENSITIVE);
				Matcher mather = pattern.matcher(stringBuffer);
				while (mather.find()) {
					result = mather.group();
				}

				result = result.substring(16, result.length() - 1);

			} catch (IOException e) {
				e.printStackTrace();
			}

			if (result != null) {
				BundleSerializable bundleSerializable = new BundleSerializable();
				bundleSerializable.review = result;
				Bundle bundle = new Bundle();
				bundle.putSerializable(Assistant.KEY_OF_SUBJECT_REVIEW,
						bundleSerializable);
				sendMessage(handler, Assistant.FETCH_REVIEW_FULL_DONE, bundle);
			} else {
				sendMessage(handler, Assistant.FETCH_REVIEW_FULL_FAIL, null);
			}
		}
		// TODO: 利用正则匹配效率较低.而且不稳定，如果标签值变化将解析失败,不够稳定

	}// ThreadFetchReviewFull.class

	// -------------------------------------------------------------------------

	/**
	 * 发布用户提交的评论,豆瓣api限制,50字以下不能发布.并需要提交一个SubjectEntry
	 * 
	 * @param handler
	 * @param title
	 * @param content
	 * @param rating
	 * @param subjectEntry
	 */
	public void startThreadPublishReview(Handler handler, String title,
			String content, int rating, SubjectEntry subjectEntry) {
		new ThreadPublishReview(handler, title, content, rating, subjectEntry)
				.start();
	}

	private class ThreadPublishReview extends Thread {
		private Handler handler;
		private String reviewTitle;
		private String reviewContent;
		private int rating;
		private SubjectEntry subjectEntry;

		public ThreadPublishReview(Handler handler, String reviewTitle,
				String reviewContent, int rating, SubjectEntry subjectEntry) {
			this.handler = handler;
			this.reviewContent = reviewContent;
			this.reviewTitle = reviewTitle;
			this.rating = rating;
			this.subjectEntry = subjectEntry;
		}

		@Override
		public void run() {
			Boolean result = App.getDouanApiInstance().publishReview(
					subjectEntry, reviewTitle, reviewContent, rating);

			if (result)
				sendMessage(handler, Assistant.FETCH_PUBLISH_REVIEW_DONE, null);
			else
				sendMessage(handler, Assistant.FETCH_PUBLISH_REVIEW_FAIL, null);
		}
	}// ThreadPublishReview.class

	// -------------------------------------------------------------------------

	/**
	 * 获取条目的评论列表,一次获取15条，在条目加载成功后会自动加载评论， 之后需要每点点击才会加载
	 * 
	 * @param handler
	 * @param id
	 *            条目id
	 * @param startIndex
	 * @param type
	 *            条目类型
	 */
	public void startThreadFetchSubjectReviews(Handler handler, String id,
			int startIndex, String type) {
		new ThreadFetchSubjectReviews(handler, id, startIndex, type).start();
	}

	private class ThreadFetchSubjectReviews extends Thread {
		private Handler handler;
		private String id;
		private int startIndex;
		private String type;

		public ThreadFetchSubjectReviews(Handler handler, String id,
				int startIndex, String type) {
			this.handler = handler;
			this.id = id;
			this.startIndex = startIndex;
			this.type = type;
		}

		@Override
		public void run() {
			ArrayList<ReviewRecord> reviewRecords = App.getDouanApiInstance()
					.getSubjectReviews(id, type, startIndex, 15);

			if (reviewRecords != null) {
				BundleSerializable bs = new BundleSerializable();
				bs.rrs = reviewRecords;
				Bundle bundle = new Bundle();
				bundle.putSerializable(Assistant.KEY_OF_SUBJECT_REVIEW, bs);
				sendMessage(handler, Assistant.FETCH_SUBJECT_REVIEW_DONE,
						bundle);
			} else {
				sendMessage(handler, Assistant.FETCH_SUBJECT_REVIEW_FAIL, null);
			}
		}
	}// ThreadFetchSubjectReviews.class

	// -------------------------------------------------------------------------

	/**
	 * 提交用户推荐，需要条目id推荐内容，内容可以为空
	 * 
	 * @param commend
	 * @param id
	 * @param handler
	 */
	public void startThreadPublishSubjectRecommand(String commend, String id,
			Handler handler) {
		new ThreadPublishSubjectRecommend(commend, id, handler).start();
	}

	private class ThreadPublishSubjectRecommend extends Thread {
		private String commend;
		private String id;
		private Handler handler;

		public ThreadPublishSubjectRecommend(String commend, String id,
				Handler handler) {
			this.commend = commend;
			this.id = id;
			this.handler = handler;
		}

		@Override
		public void run() {
			Boolean result = false;
			result = App.getDouanApiInstance().publishSubjectCommend(commend,
					id);

			if (result) {
				sendMessage(handler, Assistant.FETCH_RECOMMEND_PUBLISH_DONE,
						null);
			} else {
				sendMessage(handler, Assistant.FETCH_RECOMMEND_PUBLISH_FAIL,
						null);
			}
		}
	}// ThreadPublishSubjectRecommend.class

	// -------------------------------------------------------------------------

	/**
	 * 获取电影，图书，音乐详细内容，返回一个SubjectEnty
	 * 
	 * @param id
	 * @param type
	 * @param handler
	 */
	public void startThreadFetchSubject(String id, String isbn, String type,
			Handler handler) {
		new ThreadFetchSubjectRecord(id, isbn, type, handler).start();
	}

	private class ThreadFetchSubjectRecord extends Thread {
		private String id;
		private String type;
		private Handler handler;
		private String isbn;

		public ThreadFetchSubjectRecord(String id, String isbn, String type,
				Handler handler) {
			this.id = id;
			this.type = type;
			this.handler = handler;
			this.isbn = isbn;
		}

		@Override
		public void run() {
			try {
				SubjectRecord record = App.getDouanApiInstance()
						.getSubjectRecord(type, id, isbn);
				if (record != null) {
					Bundle bundle = new Bundle();
					bundle.putSerializable(Assistant.KEY_OF_SUBJECT, record);
					sendMessage(handler, Assistant.FETCH_SUBJECT_DONE, bundle);
				} else {
					sendMessage(handler, Assistant.FETCH_SUBJECT_FAIL, null);
				}

			} catch (IOException e) {
				e.printStackTrace();
			} catch (ServiceException e) {
				e.printStackTrace();
			}
		}
	}// ThreadFetchSubjectRecord.class

	// -------------------------------------------------------------------------

	/**
	 * 获取用户收藏的图书电影音乐列表，每次返回15条记录
	 * 
	 * @param userid
	 * @param cat
	 * @param page
	 * @param status
	 * @param handler
	 */
	public void startThreadFetchUserCollection(String userid, String cat,
			int page, String status, Handler handler) {

		ThreadFetchUserCollection fuc = new ThreadFetchUserCollection(userid,
				cat, status, page, 15, handler);
		new Thread(fuc).start();
	}

	private class ThreadFetchUserCollection implements Runnable {

		private String userID;
		private String cat;
		private String status;
		private int startIndex;
		private int maxResults;
		private Handler handler;

		//

		public ThreadFetchUserCollection(String userID, String cat,
				String status, int startIndex, int maxResults, Handler handler) {
			this.userID = userID;
			this.cat = cat;
			this.status = status;
			this.startIndex = startIndex;
			this.maxResults = maxResults;
			this.handler = handler;
		}

		@Override
		public void run() {
			int done;
			int fail;
			if (status.equals(Assistant.STATUS_BOOK_READING)
					|| status.equals(Assistant.STATUS_MUSIC_LINSTENING)) {
				done = Assistant.FETCH_BOOK_READING_DONE;
				fail = Assistant.FETCH_BOOK_READING_FAIL;
			} else if (status.equals(Assistant.STATUS_BOOK_READED)
					|| status.equals(Assistant.STATUS_MUSIC_LISTENED)) {
				done = Assistant.FETCH_BOOK_READED_DONE;
				fail = Assistant.FETCH_BOOK_READED_FAIL;
			} else if (status.equals(Assistant.STATUS_MOVICE_WATCHED)) {
				done = Assistant.FETCH_BOOK_READED_DONE;
				fail = Assistant.FETCH_BOOK_READED_FAIL;
			} else {
				done = Assistant.FETCH_BOOK_WISH_DONE;
				fail = Assistant.FETCH_BOOK_WISH_FAIL;
			}

			ArrayList<CollectionRecord> crs = App.getDouanApiInstance()
					.getUserCollectonRecords(userID, cat, null, status,
							startIndex, maxResults);
			if (crs != null) {
				Bundle bundle = new Bundle();
				BundleSerializable store = new BundleSerializable();
				store.crs = crs;
				bundle.putSerializable(Assistant.KEY_OF_COLLECTION, store);
				sendMessage(handler, done, bundle);
			} else {
				sendMessage(handler, fail, null);
			}
		}
		// TODO :返回的条数是否需要做成后台设置
	}

	// -------------------------------------------------------------------------

	/**
	 * 获取单条记录的图片线程,用于图书电影音乐列表图片
	 * 
	 * @param user
	 * @param url
	 * @param handler
	 * @param position
	 */
	public void startThreadImageDownload(String user, String url,
			Handler handler, int position) {
		new ThreadColectionImage(user, url, handler, position).start();
	}

	private class ThreadColectionImage extends Thread {
		private Handler m_handler;
		private String m_sUrl;
		private int m_iPosition;
		private String m_sStatus;

		public ThreadColectionImage(String status, String url, Handler handler,
				int position) {
			m_sStatus = status;
			m_sUrl = url;
			m_handler = handler;
			m_iPosition = position;
		}

		@Override
		public void run() {
			int done;
			int fail;
			if (m_sStatus.equals(Assistant.STATUS_BOOK_READING)) {
				done = Assistant.FETCH_BOOK_READING_IMAGE_DONE;
				fail = Assistant.FETCH_BOOK_READING_IMAGE_FAIL;
			} else if (m_sStatus.equals(Assistant.STATUS_BOOK_READED)) {
				done = Assistant.FETCH_BOOK_READED_IMAGE_DONE;
				fail = Assistant.FETCH_BOOK_READED_IMAGE_FAIL;
			} else {
				done = Assistant.FETCH_BOOK_WISH_IMAGE_DONE;
				fail = Assistant.FETCH_BOOK_WISH_IMAGE_FAIL;
			}

			Bitmap avatar = null;

			// 替换成大图， 得到更清晰的效果
			m_sUrl = m_sUrl.replaceAll("spic", "mpic");
			if (null == avatar) {
				try {
					avatar = loadImgByURL(new URL(m_sUrl));
				} catch (MalformedURLException e) {
					sendMessage(m_handler, Assistant.FETCH_IMAGE_FAIL, null);
					// e.printStackTrace();
				}
			}
			ImageSerialz image = new ImageSerialz(avatar, m_iPosition);
			Bundle bundle = new Bundle();
			bundle.putSerializable(Assistant.THREAD_IMAGE_KEY, image);
			sendMessage(m_handler, done, bundle);
		}
	}

	public void startThreadFetchUserInfo(Handler handler) {
		new ThreadFetchUserInfo(handler).start();
	}

	private class ThreadFetchUserInfo extends Thread {

		private Handler handler;

		public ThreadFetchUserInfo(Handler handler) {
			this.handler = handler;
		}

		@Override
		public void run() {
			UserInfoData userinfo = App.getDouanApiInstance()
					.getAuthorizedUser();
			if (userinfo != null) {
				Bundle bundle = new Bundle();
				bundle.putSerializable(Assistant.KEY_OF_IMAGE, userinfo);
				sendMessage(handler, Assistant.FETCH_USER_DATA_DONE, bundle);
			}
		}
	}

	public void startThreadCreateCollection(Handler handler, Context context,
			Status status, List<Tag> tags, String content,
			SubjectEntry subjectEntry, Rating rating) {
		new ThreadCreateCollection(handler, context, status, rating, tags,
				content, subjectEntry).start();
	}

	private class ThreadCreateCollection extends Thread {
		private Handler handler;
		private Context context;
		private Status status;
		private List<Tag> tags;
		private String content;
		private SubjectEntry subjectEntry;
		private Rating rating;

		public ThreadCreateCollection(Handler handler, Context context,
				Status status, Rating rating, List<Tag> tag, String content,
				SubjectEntry subjectEntry) {
			this.handler = handler;
			this.context = context;
			this.status = status;
			this.tags = tag;
			this.content = content;
			this.subjectEntry = subjectEntry;
		}

		@Override
		public void run() {
			try {

				CollectionEntry ce;
				SubjectEntry se = null;

				SharedPreferences sharedPreferences = PreferenceManager
						.getDefaultSharedPreferences(context);
				DoubanService testService = new DoubanService("mydouban",
						App.sApiKey, App.sApiSecret);
				testService.setAccessToken(sharedPreferences.getString(
						Assistant.SETTING_ACCESS_TOKEN_KEY, null),
						sharedPreferences.getString(
								Assistant.SETTING_ACCESS_TOKEN_SECRET, null));

				ce = testService.createCollection(status, subjectEntry, tags,
						rating, content);

				if (ce != null) {
					sendMessage(handler,
							Assistant.FETCH_CREATE_COLLECTION_DONE, null);
				} else {
					sendMessage(handler,
							Assistant.FETCH_CREATE_COLLECTION_FAIL, null);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ServiceException e) {
				e.printStackTrace();
			}
		}
	}

	// -------------------------------------------------------------------------

	private Bitmap loadImgByURL(URL url) {
		Bitmap image = null;
		try {
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();
			image = BitmapFactory.decodeStream(is);
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return image;
	}

	/**
	 * 将线程中获取到的数据,存入Message中，并通过handler与UI线程通信
	 * 
	 * @param handler
	 * @param msg
	 * @param data
	 */
	public void sendMessage(Handler handler, int msg, Bundle data) {
		if (handler == null)
			return;

		Message message = new Message();
		message.what = msg;
		message.setData(data);
		handler.sendMessage(message);
	}

	/**
	 * 将线程中获取到的数据,存入Message中，并通过handler与UI线程通信
	 * 
	 * @param handler
	 * @param serializ
	 * @param what
	 * @param key
	 */
	private void sendMessage(Handler handler, Serializable serializ, int what,
			String key) {
		Bundle bundle = new Bundle();
		Message msg = new Message();
		bundle.putSerializable(key, serializ);
		msg.what = what;
		msg.setData(bundle);
		handler.sendMessage(msg);
	}

	private void sendMessage(Handler handler, Bundle bundle, int what) {
		Message msg = new Message();
		msg.what = what;
		msg.setData(bundle);
		handler.sendMessage(msg);
	}

}
